package com.syl.test.encrypt;

/**
 * @author syl
 * @create 2018-08-15 17:24
 **/

import com.syl.springcloud.authorization.constant.LoginConstant;
import com.syl.springcloud.authorization.util.RasUtils;
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * ras 和 签名 test
 */
@SuppressWarnings("all")
public class RSAtest {
    public static final String KEY_ALGORITHM = "RSA";
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
    private static final int KEY_SIZE = 1024;
    private static final String PUBLIC_KEY = "RSAPublicKey";
    private static final String PRIVATE_KEY = "RSAPrivateKey";
//    public static String str_pubK = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqPvovSfXcwBbW8cKMCgwqNpsYuzF8RPAPFb7LGsnVo44JhM/xxzDyzoYtdfNmtbIuKVi9PzIsyp6rg+09gbuI6UGwBZ5DWBDBMqv5MPdOF5dCQkB2Bbr5yPfURPENypUz+pBFBg41d+BC+rwRiXELwKy7Y9caD/MtJyHydj8OUwIDAQAB";
//    public static String str_priK = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKo++i9J9dzAFtbxwowKDCo2mxi7MXxE8A8VvssaydWjjgmEz/HHMPLOhi1182a1si4pWL0/MizKnquD7T2Bu4jpQbAFnkNYEMEyq/kw904Xl0JCQHYFuvnI99RE8Q3KlTP6kEUGDjV34EL6vBGJcQvArLtj1xoP8y0nIfJ2Pw5TAgMBAAECgYAGGB8IllMwxceLhjf6n1l0IWRH7FuHIUieoZ6k0p6rASHSgWiYNRMxfecbtX8zDAoG0QAWNi7rn40ygpR5gS1fWDAKhmnhKgQIT6wW0VmD4hraaeyP78iy8BLhlvblri2nCPIhDH5+l96v7D47ZZi3ZSOzcj89s1eS/k7/N4peEQJBAPEtGGJY+lBoCxQMhGyzuzDmgcS1Un1ZE2pt+XNCVl2b+T8fxWJH3tRRR8wOY5uvtPiK1HM/IjT0T5qwQeH8Yk0CQQC0tcv3d/bDb7bOe9QzUFDQkUSpTdPWAgMX2OVPxjdq3Sls9oA5+fGNYEy0OgyqTjde0b4iRzlD1O0OhLqPSUMfAkEAh5FIvqezdRU2/PsYSR4yoAdCdLdT+h/jGRVefhqQ/6eYUJJkWp15tTFHQX3pIe9/s6IeT/XyHYAjaxmevxAmlQJBAKSdhvQjf9KAjZKDEsa7vyJ/coCXuQUWSCMNHbcR5aGfXgE4e45UtUoIE1eKGcd6AM6LWhx3rR6xdFDpb9je8BkCQB0SpevGfOQkMk5i8xkEt9eeYP0fi8nv6eOUcK96EXbzs4jV2SAoQJ9oJegPtPROHbhIvVUmNQTbuP10Yjg59+8=";
    public static String str_pubK = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKv0CgfNWqek15o9A4jFThYDasi2l7sx\n" +
        "Rr7iipnartavCJ/2NJbQbzVPet5majxvYnt7ug52mAUXr2GMmRNNIZUCAwEAAQ==";
    public static String str_priK = "MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEAq/QKB81ap6TXmj0D\n" +
        "iMVOFgNqyLaXuzFGvuKKmdqu1q8In/Y0ltBvNU963mZqPG9ie3u6DnaYBRevYYyZ\n" +
        "E00hlQIDAQABAkEAp2lbcqkuP9Wvy4znqftewPPmvS94nlmlZScuhghw/LWnve5Z\n" +
        "Qs1iQrtQqmn/mwCQCYbuB7gl7RGXRQaI64A/wQIhAN8805zrt+8d27ShE+akRbRj\n" +
        "QX70/t7rODMvaNE+cDf5AiEAxTBt1vvRXEdRrGTvjMtVT+msquI8S9xuxB+YqcGV\n" +
        "dX0CIGxEyvkbVbzyBUGoscc1utzPGs/hMM+a00n332VEXBa5AiEAstafZ/FvCdAt\n" +
        "BLtufzUSpK17ymfw46SCWSGG5b8KfEkCIQDXFUNDvNSEHJfo4+BhQasLhXM3LmtO\n" +
        "OimTtTFihWw7gQ==";

    /**
     * 使用getPublicKey得到公钥,返回类型为PublicKey
     *
     * @throws Exception
     */
    public static PublicKey getPublicKey(String key) throws Exception {
        String str = key.replaceAll("\n","");
//        System.out.println("=======公钥=====");
//        System.out.println(str);
        byte[] keyBytes;
        keyBytes = (new BASE64Decoder()).decodeBuffer(str);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * 转换私钥
     *
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String key) throws Exception {
        String str = key.replaceAll("\n","");
//        System.out.println("=======私钥=====");
//        System.out.println(str);
        byte[] keyBytes;
        keyBytes = (new BASE64Decoder()).decodeBuffer(str);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    //************************加密解密**************************
    public static byte[] encrypt(byte[] bt_plaintext) throws Exception {
        PublicKey publicKey = getPublicKey(str_pubK);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] bt_encrypted = cipher.doFinal(bt_plaintext);
        return bt_encrypted;
    }

    public static byte[] decrypt(byte[] bt_encrypted) throws Exception {
        PrivateKey privateKey = getPrivateKey(str_priK);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] bt_original = cipher.doFinal(bt_encrypted);
        return bt_original;
    }

    //***************************签名和验证*******************************
    public static byte[] sign(byte[] data) throws Exception {
        PrivateKey priK = getPrivateKey(str_priK);
        Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
        sig.initSign(priK);
        sig.update(data);
        return sig.sign();
    }

    public static boolean verify(byte[] data, byte[] sign) throws Exception {
        PublicKey pubK = getPublicKey(str_pubK);
        Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
        sig.initVerify(pubK);
        sig.update(data);
        return sig.verify(sign);
    }

    //********************main函数：加密解密和签名验证*********************
    public static void main(String[] args) throws Exception {
        String encrypt = RasUtils.encrypt("1234", LoginConstant.PUBLIC_KEY);
        System.out.println(encrypt);

        String str_plaintext = "这是一段用来测试密钥转换的明文";
        System.err.println("明文："+str_plaintext);
//        byte[] bt_cipher = encrypt(str_plaintext.getBytes());
//        System.out.println("加密后："+Base64.encodeBase64String(bt_cipher));

        byte[] bt_original = decrypt(Base64.decodeBase64("DF5oAQded1gtHYR5/47ds/7wAGUwMIVFIZgql082/G4D4kRQT1QnLXHPF+vNzubL9doTJDtf2ZBP+5SpxPWJfw=="));
        String str_original = new String(bt_original);
        System.out.println("解密结果:"+str_original);

//        String str="被签名的内容";
//        System.err.println("\n原文:"+str);
//        byte[] signature=sign(str.getBytes());
//        System.out.println("产生签名："+Base64.encodeBase64String(signature));
//        boolean status=verify(str.getBytes(), signature);
//        System.out.println("验证情况："+status);
    }
}
